﻿using Grpc.Core;
using sentrygrpc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sentryctl
{
    public class SentryClient
    {
        private Channel _channel = null;
        public void DoCommand(string[] args)
        {
            string command = args[0].ToLower().Trim();
            switch (command)
            {
                case "reload":
                    StartGrpc();
                    Reload();
                    StopGrpc();
                    break;
                case "start":
                    StartGrpc();
                    string argStart = "";
                    if (args.Length >= 2)
                    {
                        argStart = args[1];
                    }
                    else
                    {
                        argStart = "all";
                    }
                    Start(argStart);
                    StopGrpc();
                    break;
                case "stop":
                    StartGrpc();
                    string argStop = "";
                    if (args.Length >= 2)
                    {
                        argStop = args[1];
                    }
                    else
                    {
                        argStop = "all";
                    }
                    Stop(argStop);
                    StopGrpc();
                    break;
                case "status":
                    StartGrpc();
                    string argStatus = "";
                    if (args.Length >= 2)
                    {
                        argStatus = args[1];
                    }
                    else
                    {
                        argStatus = "all";
                    }
                    Status(argStatus);
                    StopGrpc();
                    break;
                case "update":
                    StartGrpc();
                    Update();
                    StopGrpc();
                    break;
                case "dir":
                    StartGrpc();
                    Dir();
                    StopGrpc();
                    break;
                case "help":
                    HelpInfo();
                    break;
            }
        }
        /// <summary>
        /// 帮助
        /// </summary>
        private void HelpInfo()
        {
            Writer.WriteLine("sentryctl reload #重新加载配置文件");
            Writer.WriteLine("sentryctl update #更新任务");
            Writer.WriteLine("sentryctl start all #启动所有任务");
            Writer.WriteLine("sentryctl stop all #停止所有任务");
            Writer.WriteLine("sentryctl start|stop program_name #启动或停止任务");
            Writer.WriteLine("sentryctl status 或者 sentryctl status all #查看所有任务状态");
            Writer.WriteLine("sentryctl dir #查看配置目录路径");
            Writer.WriteLine("sentryctl status blog #查看名字为blog的任务状态");
            Writer.Write("sentryctl help #查看sentryctl命令");
        }

        private void StartGrpc()
        {
            _channel = new Channel("localhost:13365", ChannelCredentials.Insecure);
        }

        private void StopGrpc()
        {
            if (_channel != null)
            {
                if (_channel.State == ChannelState.Ready)
                {
                    _channel.ShutdownAsync().Wait();
                }
            }
        }

        #region 查看任务状态
        /// <summary>
        /// 查看任务状态
        /// </summary>
        /// <param name="name">任务名称</param>
        private void Status(string name)
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            StatusReply reply = client.Status(new NameRequest { Name = name }, null, DateTime.UtcNow.AddSeconds(3));
            for (int i = 0; i < reply.Status.Count; i++)
            {
                var status = reply.Status[i];
                Writer.WriteStatus(status.Name, status.Type, status.Pid, status.Uptime);
                if (i < reply.Status.Count - 1)
                {
                    Writer.WriteEnter();
                }
            }
        }
        #endregion

        #region 重新加载配置
        /// <summary>
        /// 重新加载配置
        /// </summary>
        private void Reload()
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            DefaultReply reply = client.Reload(new DefaultRequest { Data = 1 }, null, DateTime.UtcNow.AddSeconds(3));
            Writer.Write(reply.Message);
        }
        #endregion

        #region 更新任务
        /// <summary>
        /// 更新任务
        /// </summary>
        private void Update()
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            DefaultReply reply = client.Update(new DefaultRequest { Data = 1 }, null, DateTime.UtcNow.AddSeconds(3));
            Writer.Write(reply.Message);
        }
        #endregion

        #region 查看配置目录
        /// <summary>
        /// 查看配置目录
        /// </summary>
        private void Dir()
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            DefaultReply reply = client.Dir(new DefaultRequest { Data = 1 }, null, DateTime.UtcNow.AddSeconds(3));
            Writer.Write(reply.Message);
        }
        #endregion

        #region 开始任务
        /// <summary>
        /// 开始任务
        /// </summary>
        /// <param name="name">任务名</param>
        private void Start(string name)
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            DefaultReply reply = client.Start(new NameRequest { Name = name }, null, DateTime.UtcNow.AddSeconds(3));
            Writer.Write(reply.Message);
        }
        #endregion

        #region 停止任务
        /// <summary>
        /// 停止任务
        /// </summary>
        /// <param name="name">任务名称</param>
        private void Stop(string name)
        {
            var client = new Sentryprotocol.SentryprotocolClient(_channel);
            DefaultReply reply = client.Stop(new NameRequest { Name = name }, null, DateTime.UtcNow.AddSeconds(3));
            Writer.Write(reply.Message);
        } 
        #endregion
    }
}
